/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package wh.server.util;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import wh.*;
import wh.server.*;

/**
 *
 * @author Dave
 */
public class Parser {
    static String configFile = "config.xml";

    public static void parseFile(HashMap<Integer, Method> opcodeMap) {
        try {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            parser.parse(new File(configFile), new Handler(opcodeMap));
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(Parser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SAXException ex) {
            Logger.getLogger(Parser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Parser.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

class Handler extends DefaultHandler {
    static HashMap<Integer, Method> opcodeMap;
    Stack<String> lastNode = new Stack<String>();
    int opcode;

    public Handler(HashMap<Integer, Method> map) {
        opcodeMap = map;
    }

    @Override
    public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
        String node = lastNode.pop().toString();
				if(arg0 == null) {
					System.out.println("arg0 is null... wtf?");
					return;
				}
				String chars = new String(arg0, arg1, arg2);
				System.out.println("Characters: " + chars);
        if (node.equals("opcode")) {
						opcode = Integer.parseInt(chars);
						//System.out.println("Characters: " + new String(arg0));
            //opcode = Integer.parseInt(new String(arg0));;
        } else if (node.equals("function")) {
            try {
								Class[] p = {Player.class};
								System.out.println("Class array not the problem");
								Class f = Class.forName("wh.server.Functions");
								System.out.println("Loading class not the problem");
								Method m = f.getMethod(chars, p);
								System.out.println("Getting method not the problem");
                opcodeMap.put(opcode, m);
								System.out.println("Finished");
            } catch (ClassNotFoundException ex) {
                Logger.getLogger(Handler.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NoSuchMethodException ex) {
                Logger.getLogger(Handler.class.getName()).log(Level.SEVERE, null, ex);
            }  catch (SecurityException ex) {
                Logger.getLogger(Handler.class.getName()).log(Level.SEVERE, null, ex);
            } catch (NullPointerException ex) {
							ex.printStackTrace();
						}
        }
				lastNode.push(node);
        super.characters(arg0, arg1, arg2);
    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }

    @Override
    public void endElement(String arg0, String arg1, String arg2) throws SAXException {
				System.out.println("Element ended: " + arg2);
        lastNode.pop();
        super.endElement(arg0, arg1, arg2);
    }

    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
    }

    @Override
    public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException {
        System.out.println("Element started: " + arg2);
				lastNode.push(arg2);
        super.startElement(arg0, arg1, arg2, arg3);
    }
}
